import { Injectable, NestMiddleware } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { jsonParseObjProps, jsonStringifyObjProps } from "st-common-core";
import {JsonHeaderNameConst, ResObjPropNameConst} from 'st-common-req'
import { EnvNameEnum } from "../../env";
import { getReqDataFromReq, setReqData } from "../../req";
import { modifyResData } from '../../res'

/**
 * 对请求数据对象中的属性进行 JSON 解析、对响应对象中数据的属性进行 JSON 序列化的全局中间件
 */
@Injectable()
export class ReqResJsonHandleMiddleware implements NestMiddleware {

  constructor(private readonly configService: ConfigService) {
  }

  use(req: any, res: any, next: () => void) {
    // 如果在环境变量中配置开启了对请求数据对象中的属性进行 JSON 解析，且请求数据对象中的属性经过 JSON 序列化处理
    if (
      this.configService.get<boolean>(EnvNameEnum.REQ_DATA_IS_JSON) &&
      req.headers[JsonHeaderNameConst.IS_JSON_STRINGIFY] === "true"
    ) {
      // 获取请求数据
      const reqData = getReqDataFromReq(req);
      // 对请求数据对象中的属性进行 JSON 解析
      setReqData(req, jsonParseObjProps({
        obj: reqData
      }));
    }
    // 如果在环境变量中配置开启了对响应对象中数据的属性进行 JSON 序列化
    if (this.configService.get<boolean>(EnvNameEnum.RES_DATA_IS_JSON)) {
      // 对响应对象中数据的属性进行 JSON 序列化
      modifyResData(res, (resData) => {
        // 对响应对象中数据的属性进行 JSON 序列化
        resData = jsonStringifyObjProps({
          obj: resData,
          excludeProps: [
            ResObjPropNameConst.IS_ENCRYPT,
            ResObjPropNameConst.IS_JSON_STRINGIFY
          ]
        });
        // 标记响应数据对象中的属性已经过 JSON 序列化处理
        resData[ResObjPropNameConst.IS_JSON_STRINGIFY] = true;
        return resData;
      });
    }
    // 继续处理请求
    next();
  }
}
